#include "RendererParams.h"

using namespace Nezha;

	const _string RendererParam::msNames[MAX_RPT_NUM] =
	{
		// basic matrices
		"W_MATRIX",
		"V_MATRIX",
		"P_MATRIX",
		"WV_MATRIX",
		"VP_MATRIX",
		"WVP_MATRIX",

		// transpose
		"W_MATRIX_T",
		"V_MATRIX_T",
		"P_MATRIX_T",
		"WV_MATRIX_T",
		"VP_MATRIX_T",
		"WVP_MATRIX_T",

		// inverse
		"W_MATRIX_I",
		"V_MATRIX_I",
		"P_MATRIX_I",
		"WV_MATRIX_I",
		"VP_MATRIX_I",
		"WVP_MATRIX_I",

		// inverse transpose
		"W_MATRIX_I_T",
		"V_MATRIX_I_T",
		"P_MATRIX_I_T",
		"WV_MATRIX_I_T",
		"VP_MATRIX_I_T",
		"WVP_MATRIX_I_T",

		"UNKNOWN",

		// camera
		"CAM_LOCAL_POS",
		"CAM_LOCAL_DIR",
		"CAM_LOCAL_UP",
		"CAM_LOCAL_RIGHT",
		"CAM_WORLD_POS",
		"CAM_WORLD_DIR",
		"CAM_WORLD_UP",
		"CAM_WORLD_RIGHT",

		// projector
		"PROJ_LOCAL_POS",
		"PROJ_LOCAL_DIR",
		"PROJ_LOCAL_UP",
		"PROJ_LOCAL_RIGHT",
		"PROJ_WORLD_POS",
		"PROJ_WORLD_DIR",
		"PROJ_WORLD_UP",
		"PROJ_WORLD_RIGHT",

		// light
		"LIT0_LOCAL_POS",
		"LIT0_LOCAL_DIR",
		"LIT0_WORLD_POS",
		"LIT0_WORLD_DIR",
		"LIT0_COLOR",
		"LIT0_SPOTCUTOFF",
		"LIT0_ATTENUATION",
		"LIT1_LOCAL_POS",
		"LIT1_LOCAL_DIR",
		"LIT1_WORLD_POS",
		"LIT1_WORLD_DIR",
		"LIT1_COLOR",
		"LIT1_SPOTCUTOFF",
		"LIT1_ATTENUATION",
		"LIT2_LOCAL_POS",
		"LIT2_LOCAL_DIR",
		"LIT2_WORLD_POS",
		"LIT2_WORLD_DIR",
		"LIT2_COLOR",
		"LIT2_SPOTCUTOFF",
		"LIT2_ATTENUATION",
		"LIT3_LOCAL_POS",
		"LIT3_LOCAL_DIR",
		"LIT3_WORLD_POS",
		"LIT3_WORLD_DIR",
		"LIT3_COLOR",
		"LIT3_SPOTCUTOFF",
		"LIT3_ATTENUATION",
		"LIT4_LOCAL_POS",
		"LIT4_LOCAL_DIR",
		"LIT4_WORLD_POS",
		"LIT4_WORLD_DIR",
		"LIT4_COLOR",
		"LIT4_SPOTCUTOFF",
		"LIT4_ATTENUATION",
		"LIT5_LOCAL_POS",
		"LIT5_LOCAL_DIR",
		"LIT5_WORLD_POS",
		"LIT5_WORLD_DIR",
		"LIT5_COLOR",
		"LIT5_SPOTCUTOFF",
		"LIT5_ATTENUATION",
		"LIT6_LOCAL_POS",
		"LIT6_LOCAL_DIR",
		"LIT6_WORLD_POS",
		"LIT6_WORLD_DIR",
		"LIT6_COLOR",
		"LIT6_SPOTCUTOFF",
		"LIT6_ATTENUATION",
		"LIT7_LOCAL_POS",
		"LIT7_LOCAL_DIR",
		"LIT7_WORLD_POS",
		"LIT7_WORLD_DIR",
		"LIT7_COLOR",
		"LIT7_SPOTCUTOFF",
		"LIT7_ATTENUATION",

		"UNKNOWN",

		// TODO add renderer parameter types
	};

PMap<_string, RendererParamsType> RendererParam::mName2TypeMap;

RendererParam::RendererParam()
	:mRendererParamType(RPT_UNKNOWN)
{

}

void RendererParam::create(RendererParamsType rpt)
{
	mRendererParamType = rpt;
	ShaderParamDesc desc;
	desc.Category = getCategory();
	strcpy(desc.Name, msNames[rpt].c_str());
	desc.DataType = RPT2ShdParamDataType(rpt);

	ShaderParameter::create(desc);
}

u32 RendererParam::DetermineParamSize(RendererParamsType rpt)
{
	if(rpt >= 0 && rpt < RPT_NOUSED_MATRIX)
	{
		return sizeof(Matrix4x4);
	}
	else if(rpt < RPT_NOUSED_FLOAT4)
	{
		return sizeof(Vector4);
	}

	return 0;
}

ShaderParamDataType RendererParam::RPT2ShdParamDataType(RendererParamsType rpt)
{
	if(rpt >= 0 && rpt < RPT_NOUSED_MATRIX)
	{
		return SPDT_FLOAT4X4;
	}
	else if(rpt < RPT_NOUSED_FLOAT4)
	{
		return SPDT_FLOAT4;
	}

	return SPDT_USER;
}

RendererParamsType RendererParam::NameToType(const _string& name)
{
	PMap<_string, RendererParamsType>::iterator it = mName2TypeMap.find(name);
	if(it != mName2TypeMap.end())
	{
		return it->second;
	}

	return RPT_UNKNOWN;
}